/**
 * 二维最大池化实现，主要用于NMS
 */ 

#ifndef HITSZ_DIP_EX3_MAXPOOL2D_H
#define HITSZ_DIP_EX3_MAXPOOL2D_H

#include <iostream>
#include <vector>
#include <algorithm>
// #include <chrono>

#include <opencv2/opencv.hpp>

using namespace std;
/**
 * @brief 二维最大池化，只支持stride = 1和h=w的kernel
 * 
 * 
 */ 
namespace dip{
    void maxpooling2d(const cv::Mat& mat,cv::Mat &dst,int kernel_size,int stride = 1,int pad_value=0)
    {
        int w = mat.cols;
        int h = mat.rows;
        int top,bottom,left,right;
        //计算padding
        left = (kernel_size-1)/2;
        right = kernel_size-1 - left;
        top = (kernel_size-1)/2;
        bottom = kernel_size-1 - top;

        cv::Mat pad_img;
        cv::Mat res_img(h,w,CV_32FC1, cv::Scalar(0));
        //做padding,实际上最好不要这样实现,但是我不会...
        cv::copyMakeBorder(mat,pad_img,top,bottom,left,right,cv::BORDER_CONSTANT,cv::Scalar(pad_value));

        // float nms_data_ptr = new float[mat.rows*mat.cols];//创建数据指针
        float* res_data_ptr = res_img.ptr<float>();
        for(int i=0;i<mat.rows;i++)
        {
            for (int j = 0; j <mat.cols; j++)
            {
                int start_x = j*stride;
                int start_y = i*stride;
                vector<int> temp;
                for(int ii=0;ii<kernel_size;ii++)
                {
                    for (int jj = 0; jj < kernel_size; jj++)
                    {
                        temp.push_back(pad_img.at<float>(start_y + jj,start_x + ii));
                    }
                }
                sort(temp.begin(), temp.end());
                res_img.at<uchar>(i,j) = temp[temp.size() - 1];
                res_data_ptr++;
                // res[i][j] = temp[temp.size() - 1];
            }
        }
        res_img.copyTo(dst);
    }

}
#endif